﻿using System.Collections.Generic;

namespace Sidvall.Serialization
{
    public class PropertyItemCollection : System.Collections.ObjectModel.Collection<PropertyItem>
    {
        #region Public Members

        #region Add

        public PropertyItem Add(string propertyName, int? displayPosition)
        {
            return Add(propertyName, displayPosition, null);
        }
        public PropertyItem Add(string propertyName, int? displayPosition, string entityName)
        {
            return Add(propertyName, displayPosition, entityName, null, PropertyItemType.Default, null);
        }
        private PropertyItem Add(string propertyName, int? displayPosition, string entityName, string newPropertyName, PropertyItemType type, NullValueHandlingPolicy? nullValueHandlingPolicy)
        {
            var item = new PropertyItem()
            {
                EntityName = entityName,
                PropertyName = propertyName,
                NewPropertyName = newPropertyName,
                PropertyItemType = type,
                DisplayPosition = displayPosition,
                NullValueHandlingPolicy = nullValueHandlingPolicy,
            };
            Add(item);
            return item;
        }

        #endregion
        #region AddArrayItem

        public PropertyItem AddArrayItem(string propertyName, int? displayPosition)
        {
            return AddArrayItem(propertyName, displayPosition, null);
        }
        public PropertyItem AddArrayItem(string propertyName, int? displayPosition, string entityName)
        {
            var item = Add(propertyName, displayPosition, entityName);
            item.IsArray = true;
            return item;
        }

        #endregion
        #region AddExcludedItem

        public PropertyItem AddExcludedItem(string propertyName)
        {
            return AddExcludedItem(propertyName, null);
        }
        public PropertyItem AddExcludedItem(string propertyName, string entityName)
        {
            return AddExcludedItem(propertyName, entityName, false);
        }
        public PropertyItem AddExcludedItem(string propertyName, string entityName, bool allExceptThis)
        {
            if (!allExceptThis)
                return Add(propertyName, null, entityName, null, PropertyItemType.Exclude, null);
            else
                return Add(propertyName, null, entityName, null, PropertyItemType.ExcludeAllExceptThis, null);
        }

        #endregion
        #region AddNullableItem

        public PropertyItem AddNullableItem(string propertyName, NullValueHandlingPolicy nullValueHandlingPolicy)
        {
            return AddNullableItem(propertyName, nullValueHandlingPolicy, null);
        }
        public PropertyItem AddNullableItem(string propertyName, NullValueHandlingPolicy nullValueHandlingPolicy, string entityName)
        {
            return AddNullableItem(propertyName, nullValueHandlingPolicy, entityName, null);
        }
        public PropertyItem AddNullableItem(string propertyName, NullValueHandlingPolicy nullValueHandlingPolicy, string entityName, int? displayPosition)
        {
            return Add(propertyName, displayPosition, entityName, null, PropertyItemType.Default, nullValueHandlingPolicy);
        }

        #endregion
        #region AddRenamedItem

        public PropertyItem AddRenamedItem(string propertyName, string newPropertyName)
        {
            return AddRenamedItem(propertyName, newPropertyName, null);
        }
        public PropertyItem AddRenamedItem(string propertyName, string newPropertyName, string entityName)
        {
            return AddRenamedItem(propertyName, newPropertyName, entityName, null);
        }
        public PropertyItem AddRenamedItem(string propertyName, string newPropertyName, string entityName, int? displayPosition)
        {
            return Add(propertyName, displayPosition, entityName, newPropertyName, PropertyItemType.Default, null);
        }

        #endregion
        #region AddRange

        public void AddRange(IEnumerable<PropertyItem> items)
        {
            if (items == null)
                return;
            foreach (var item in items)
                Add(item);
        }

        #endregion

        #region Deserialize

        public static PropertyItemCollection Deserialize(string value)
        {
            return Deserialize(value, null);
        }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
        public static PropertyItemCollection Deserialize(string value, PropertyItemCollection defaultValue)
        {
            return Sidvall.Serialization.SerializerManager.Current.TryDeserialize<PropertyItemCollection>(value, () =>
            {
                return defaultValue;
            });
        }

        #endregion
        #region Serialize

        public string Serialize()
        {
            return Serialize(this);
        }
        public static string Serialize(PropertyItemCollection context)
        {
            return Sidvall.Serialization.SerializerManager.Current.SerializeObject(context);
        }

        #endregion

        #endregion
        #region Constructors

        public PropertyItemCollection()
        {
        }
        public PropertyItemCollection(IEnumerable<PropertyItem> items)
        {
            AddRange(items);
        }

        #endregion
    }
}
